﻿using System;
using System.Runtime.InteropServices;

namespace Eneta.Portal.Forum.Rss
{
    [Serializable, StructLayout(LayoutKind.Sequential)]
    public struct DBBool
    {
        public static readonly DBBool Null;
        public static readonly DBBool False;
        public static readonly DBBool True;
        private sbyte value;
        private DBBool(int value)
        {
            this.value = (sbyte)value;
        }

        public bool IsNull
        {
            get
            {
                return (this.value == 0);
            }
        }
        public bool IsFalse
        {
            get
            {
                return (this.value < 0);
            }
        }
        public bool IsTrue
        {
            get
            {
                return (this.value > 0);
            }
        }
        public static implicit operator DBBool(bool x)
        {
            if (!x)
            {
                return False;
            }
            return True;
        }

        public static explicit operator bool(DBBool x)
        {
            if (x.value == 0)
            {
                throw new InvalidOperationException();
            }
            return (x.value > 0);
        }

        public static DBBool operator ==(DBBool x, DBBool y)
        {
            if ((x.value == 0) || (y.value == 0))
            {
                return Null;
            }
            if (x.value != y.value)
            {
                return False;
            }
            return True;
        }

        public static DBBool operator !=(DBBool x, DBBool y)
        {
            if ((x.value == 0) || (y.value == 0))
            {
                return Null;
            }
            if (x.value == y.value)
            {
                return False;
            }
            return True;
        }

        public static DBBool op_LogicalNot(DBBool x)
        {
            return new DBBool(-x.value);
        }

        public static DBBool operator &(DBBool x, DBBool y)
        {
            return new DBBool((x.value < y.value) ? x.value : y.value);
        }

        public static DBBool operator |(DBBool x, DBBool y)
        {
            return new DBBool((x.value > y.value) ? x.value : y.value);
        }

        public static bool operator true(DBBool x)
        {
            return (x.value > 0);
        }

        public static bool operator false(DBBool x)
        {
            return (x.value < 0);
        }

        //public override bool Equals(object o)
        //{
        //    try
        //    {
        //        return (this == ((DBBool) o));
        //    }
        //    catch
        //    {
        //        return false;
        //    }
        //}

        public override int GetHashCode()
        {
            return this.value;
        }

        public override string ToString()
        {
            switch (this.value)
            {
                case -1:
                    return "false";

                case 0:
                    return "DBBool.Null";

                case 1:
                    return "true";
            }
            throw new InvalidOperationException();
        }

        static DBBool()
        {
            Null = new DBBool(0);
            False = new DBBool(-1);
            True = new DBBool(1);
        }
    }
}
